package com.hope.reflection.question;

import java.lang.reflect.Method;
import java.sql.SQLOutput;

/**
 * 通过反射调用方法
 */
public class ReflecAccessMethod {
    public static void main(String[] args) throws Exception {
        //1. 先获取到Boss类到Class对象
        Class<?> bossClass = Class.forName("com.hope.reflection.question.Boss");
        //2. 创建对象
        Object o = bossClass.getConstructor().newInstance();//o的运行类型Boss
        //3. 调用public 方法
        Method hi = bossClass.getDeclaredMethod("hi",String.class);
        hi.invoke(o,"蔡江鸿");

        //4. 调用private static 方法
        //4.1得到say方法对象
        Method say = bossClass.getDeclaredMethod("say", int.class, String.class, char.class);
        //4.2因为say方法是private，所以需要爆破，原理和前面讲的构造器和属性一样
        say.setAccessible(true);
        System.out.println(say.invoke(o, 10, "的蔡江鸿", '帅'));
        //因为say方法是静态的，在类加载对时候，静态方法也加载了，所以还可以这样调用，可以传入null
        System.out.println(say.invoke(null, 10, "的蔡江鸿", '帅'));

        //5. 在反射中，如果方法有返回值，统一返回object，但是它运行类型和方法定义的返回类型一致
        Object invoke = say.invoke(null, 20, "的蔡江鸿", '帅');
        System.out.println("invoke的运行类型"+invoke.getClass());//String
    }
}

class Boss {
    public int age;
    private static String name;


    public Boss() { //无参构造器 public
    }

    private static String say(int n, String s, char c) { //静态方法
        return n + " " + s + " " + c;
    }

    public void hi(String s) {      //普通的public方法
        System.out.println("hi" + s);
    }

}